#include <GLTools.h>
//#include <GLMatrixStack.h>
//#include <GLFrame.h>
//#include <GLFrustum.h>
//#include <GLGeometryTransform.h>
//#include <GLBatch.h>
//#include <math.h>
#include <GLShaderManager.h>
#include <GL\glut.h>
#include <GL\freeglut.h>

int		winHeight	= 700;
int		winWidth	= 700;
float	aspect		= 1;

// Eye position from camera
float eye[3] = {0.0f, 0.0f, -30.0f};
// Reference for the camera to look at
float center[3] = {0.0f, 0.0f, 0.0f};
// Specify the upwards vector
float up[3] = {0.0f, 1.0f, 0.0f};

//GLFrustum		viewFrustum;
//GLShaderManager	shaderMan;
//GLTriangleBatch	torusBatch;

// Resize window function
void resize(int w, int h)
{
	winHeight = h;
	winWidth = w;
	aspect = (float)winWidth / (float)winHeight;

	// Stop divide by zero occurring
	if(winHeight == 0)
		winHeight = 1;

	// Draw area
	glViewport(0, 0, winWidth, winHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Set perspective projection
	gluPerspective(45.0f, aspect, 1.0f, 600.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
//	viewFrustum.SetPerspective(45.0f, aspect, 1.0f, 600.0f);

	// Clear background colour
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
	// Clear depth buffer
	glClearDepth(1.0f);
	// Enable depth testing
	glEnable(GL_DEPTH_TEST);
	// Allow for anything that is less or equal than a specific value to be rendered
	glDepthFunc(GL_LEQUAL);
	glLineWidth(4);
}

// Display func
void render()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

#pragma region Matrices&Batch
/*
	// Matrices
	M3DMatrix44f mTran, mRot, mModel, mProj;

	// Translation Matrix
	m3dTranslationMatrix44(mTran, 0.0f, 0.0f, -35.0f);
	// Rotation Matrix
	m3dRotationMatrix44(mRot, m3dDegToRad(45.0f), 30.0f, 1.0f, 0.0f);
	// Add rot to trans, store in Model
	m3dMatrixMultiply44(mModel, mTran, mRot);
	// Add Model to Proj
	m3dMatrixMultiply44(mProj, viewFrustum.GetProjectionMatrix(), mModel);
	// Pass matrix to shader and render torus
	GLfloat black[] = {0.0f, 0.0f, 0.0f, 1.0f};
	shaderMan.UseStockShader(GLT_SHADER_FLAT, mProj, black);
	torusBatch.Draw();
*/
#pragma endregion Matrices&Batch

#pragma region Camera&Torus

	// set the cameras position
	gluLookAt(	eye[0], eye[1], eye[2],
				center[0], center[1], center[2],
				up[0], up[1], up[2]);

	// rotate around x axis for better angle
	glRotatef(45, 30, 1, 0);


	// Outer Track
	glColor3f(0.0f, 1.0f, 0.0f);
	glutSolidTorus(0.3, 10.0, 5, 30);
	glColor3f(0.0f, 0.0f, 0.0f);
	glutWireTorus(0.3, 10.0, 5, 30);
	// Inner Track
	glColor3f(1.0f, 0.0f, 0.0f);
	glutSolidTorus(0.3, 9.3f, 5, 30);
	glColor3f(0.0f, 0.0f, 0.0f);
	glutWireTorus(0.3, 9.3f, 5, 30);

#pragma endregion Camera&Torus

	// swap buffers
	glutSwapBuffers();
	// Refresh scene
	glutPostRedisplay();
}

/*
void Setup()
{
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
	glEnable(GL_DEPTH_TEST);
	shaderMan.InitializeStockShaders();

	gltMakeTorus(torusBatch, 10, 0.5, 30, 5);

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
*/

int main(int argc, char* argv[])
{
	gltSetWorkingDirectory(argv[0]);

	// Init window and properties
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	glutInitWindowSize(winHeight, winWidth);
	glutCreateWindow("COURSEWORK 0.1");

	// Init and set callbacks for resize and display
	glutReshapeFunc(resize);
	glutDisplayFunc(render);

	// Init OpenGL context via GLEW Wrangler System
	GLenum err = glewInit();
	if(GLEW_OK != err)
	{
		fprintf(stderr, "GLEW ERROR: %s\n", glewGetErrorString(err));
		return 1;
	}

//	Setup();

	// Entry point loop
	glutMainLoop();

	return 0;
}
